package com.xjoyt.pay.gateway.controllers;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.google.gson.Gson;
import com.xjoyt.pay.controllers.AbstractController;
import com.xjoyt.pay.gateway.constants.RedisConstant;
import com.xjoyt.pay.gateway.vo.TokenSession;
import com.xjoyt.pay.master.po.Distributor;
import com.xjoyt.pay.master.po.Merchant;

public abstract class GatewayAbstractController extends AbstractController {

    @Autowired
    protected StringRedisTemplate redisTemplate;

    /**
     * 获取代理商
     * 
     * @param accessToken
     * @return
     */
    protected Distributor getDistributor(String accessToken) {
        String value = redisTemplate.opsForValue()
                .get(RedisConstant.REDIS_KEY_ACCESS_TOKEN + accessToken);
        if (StringUtils.isBlank(value)) {
            return null;
        }
        Gson gson = new Gson();
        @SuppressWarnings("unchecked")
        TokenSession<Map<String, Object>> token = gson.fromJson(value,
                TokenSession.class);
        if (token == null || token.auth == null || token.type != 1) {
            return null;
        }
        String json = gson.toJson(token.auth);
        return gson.fromJson(json, Distributor.class);
    }

    /**
     * 获取商户
     * 
     * @param accessToken
     * @return
     */
    protected Merchant getMerchant(String accessToken) {
        String value = redisTemplate.opsForValue()
                .get(RedisConstant.REDIS_KEY_ACCESS_TOKEN + accessToken);
        if (StringUtils.isBlank(value)) {
            return null;
        }
        Gson gson = new Gson();
        @SuppressWarnings("unchecked")
        TokenSession<Map<String, Object>> token = gson.fromJson(value,
                TokenSession.class);
        if (token == null || token.auth == null || token.type != 0) {
            return null;
        }
        String json = gson.toJson(token.auth);
        return gson.fromJson(json, Merchant.class);
    }

    protected String createAccessToken(Distributor entity) {
        String accessToken = (UUID.randomUUID().toString()
                + UUID.randomUUID().toString()).replaceAll("-",
                        StringUtils.EMPTY);

        TokenSession<Distributor> token = new TokenSession<>();
        token.type = 1;
        token.auth = entity;
        redisTemplate.opsForValue().set(
                RedisConstant.REDIS_KEY_ACCESS_TOKEN + accessToken,
                toJson(token), RedisConstant.REDIS_COOLDOWN_TIME_ACCESS_TOKEN,
                TimeUnit.HOURS);
        redisTemplate.opsForValue().set(
                RedisConstant.REDIS_KEY_ACCESS_TOKEN + "distributor."
                        + entity.no + "." + accessToken,
                entity.id, RedisConstant.REDIS_COOLDOWN_TIME_ACCESS_TOKEN,
                TimeUnit.HOURS);
        return accessToken;
    }

    protected String createAccessToken(Merchant entity) {
        String accessToken = (UUID.randomUUID().toString()
                + UUID.randomUUID().toString()).replaceAll("-",
                        StringUtils.EMPTY);

        TokenSession<Merchant> token = new TokenSession<>();
        token.type = 0;
        token.auth = entity;
        redisTemplate.opsForValue().set(
                RedisConstant.REDIS_KEY_ACCESS_TOKEN + accessToken,
                toJson(token), RedisConstant.REDIS_COOLDOWN_TIME_ACCESS_TOKEN,
                TimeUnit.HOURS);
        redisTemplate.opsForValue().set(
                RedisConstant.REDIS_KEY_ACCESS_TOKEN + "merchant." + entity.no
                        + "." + accessToken,
                entity.id, RedisConstant.REDIS_COOLDOWN_TIME_ACCESS_TOKEN,
                TimeUnit.HOURS);
        return accessToken;
    }
}
